#include "PostProcess.h"

Effect::Effect()
{
	width = ScreenWidth();
	height = ScreenHeight();

	framebuffer =0;
	depthbuffer = 0;

	ok = 0;
	Init();
}
Effect::Effect(unsigned int width_, unsigned int height_)
{
	width = width_;
	height = height_;
	framebuffer =0;
	depthbuffer = 0;

	ok = 0;
	Init();
}
Effect::~Effect()
{
	if(depthbuffer)
	{
		glDeleteRenderbuffers(1,&depthbuffer);
	}

	if(framebuffer)
	{
		glDeleteFramebuffers(1,&framebuffer);
	}
}

void Effect::Draw()
{
	if(tex)tex->Bind();
	if(shader)shader->Bind();
	Blend(blend);
	Rect(0,0,ScreenWidth(),ScreenHeight(),r,g,b,a);
	if(shader)shader->UnBind();
	if(tex)tex->UnBind();
}

void Effect::BindShader(Shader *sh)
{
	shader = sh;
}

unsigned int Effect::GetWidth()
{
	return width;
}
unsigned int Effect::GetHeight()
{
	return height;
}

void Effect::Init()
{
	glGenFramebuffers(1,&framebuffer);
	glBindFramebuffer(GL_FRAMEBUFFER,framebuffer);

	glGenRenderbuffers(1,&depthbuffer);
	glBindRenderbuffer(GL_RENDERBUFFER,depthbuffer);
	glRenderbufferStorage(GL_RENDERBUFFER,GL_DEPTH_COMPONENT24,width,height);
	glFramebufferRenderbuffer(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT_EXT,GL_RENDERBUFFER,depthbuffer);

	Blend(BM_ADD);
	Color(0.5f,0.5f,0.5f,0.5f);
	shader=0;
	tex=0;
	glBindFramebuffer( GL_FRAMEBUFFER_EXT, 0 );

	for(int i=0;i<16;++i)
		bindaded[i] =  0;

	bool ok = glCheckFramebufferStatus ( GL_FRAMEBUFFER_EXT ) ==
                                                  GL_FRAMEBUFFER_COMPLETE_EXT;
	debug::Log<<"ok :"<<ok<<std::endl;

}

void Effect::Blend(unsigned char mode)
{
	blend = mode;
}

void Effect::Bind()
{
	if(!framebuffer)return;
	glBindFramebuffer(GL_FRAMEBUFFER_EXT,framebuffer);

	int cnt =0;
	for(int i=0;i<16;i++)
	{
		cnt+=bindaded[i];
	}

	if(cnt>1)
	{
		//debug::Log<<"cnt:"<<cnt<<std::endl;
		GLenum *buffers = new GLenum[cnt];
		
		int ci=0;
		for(int i=0;i<16;i++)
		{
			if(bindaded[i])
			{
				buffers[ci] = GL_COLOR_ATTACHMENT0 + i;
				ci++;
				//cnt+=bindaded[i];
			}
		}

		glDrawBuffers(cnt,buffers);
		delete[] buffers;
	}

//	glReadBuffer         ( GL_COLOR_ATTACHMENT0_EXT );
//	glDrawBuffer         ( GL_COLOR_ATTACHMENT0_EXT );
}

void Effect::UnBind()
{
	if(!framebuffer)return;
	glBindFramebuffer(GL_FRAMEBUFFER_EXT,0);
}

void Effect::Color(float r_,float g_,float b_,float a_=1.0f)
{
	r=r_;
	g=g_;
	b=b_;
	a=a_;
}

void Effect::BindTexture(Texture *tex_,int layer = 0)
{
	if(layer<0 || layer>=caps::MRTLayers)
		return;

	tex = tex_;
	glBindFramebuffer(GL_FRAMEBUFFER_EXT,framebuffer);
	//glBindTexture( GL_TEXTURE_2D, tex->GetGLTexture() );
	if(tex!=0)
	{
		glFramebufferTexture2D( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + layer,
                                tex->GetGLTextType(), tex->GetGLTexture(), 0 );
		bindaded[layer] = 1;
	}
	else
	{
		glFramebufferTexture2D( GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + layer,
                                0, 0, 0 );
		bindaded[layer]=0;
	}

	glBindFramebuffer(GL_FRAMEBUFFER_EXT,0);
}

void Effect::BindDepthTexture(Texture *tex_)
{
	//tex = tex_;
	glBindFramebuffer(GL_FRAMEBUFFER_EXT,framebuffer);
	//glBindTexture( GL_TEXTURE_2D, tex->GetGLTexture() );
	glFramebufferTexture2D( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT,
                                tex->GetGLTextType(), tex->GetGLTexture(), 0 );
	
	glBindFramebuffer(GL_FRAMEBUFFER_EXT,0);
}